textview: Use paintables instead of textures, and fix the support
authorAlexander Larsson <alexl@redhat.com>
Thu, 6 Feb 2020 15:33:34 +0000 (16:33 +0100)
committerAlexander Larsson <alexl@redhat.com>
Thu, 6 Feb 2020 16:47:56 +0000 (17:47 +0100)
This changes gtk_text_buffer_insert_texture() to
gtk_text_buffer_insert_paintable() which is strictly more useful
(as textures are paintables). It also fixes the code to actually
support drawing the paintables (as well as tracking changes
to the paintables.

13 files changed:
demos/gtk-demo/textview.c
gtk/gtktextbtree.c
gtk/gtktextbtree.h
gtk/gtktextbuffer.c
gtk/gtktextbuffer.h
gtk/gtktextchild.c
gtk/gtktextchildprivate.h
gtk/gtktextiter.c
gtk/gtktextiter.h
gtk/gtktextlayout.c
gtk/gtktextsegment.h
gtk/gtktexttypes.h
testsuite/gtk/textbuffer.c

index 01eb503b858bcc78c6e919155928d18b773d9bbf..2a2298a14c6ca5f9c5916f6fee139c3bd54c3cfb 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <gtk/gtk.h>
 #include <stdlib.h> /* for exit() */
+#include "paintable.h"
 
 static void easter_egg_callback (GtkWidget *button, gpointer data);
 
@@ -130,20 +131,18 @@ insert_text (GtkTextView *view)
   GtkTextBuffer *buffer = gtk_text_view_get_buffer (view);
   GtkTextIter iter;
   GtkTextIter start, end;
-  GdkTexture *texture;
   GtkIconTheme *icon_theme;
   GtkIconPaintable *icon;
+  GdkPaintable *nuclear;
 
   icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
   icon = gtk_icon_theme_lookup_icon (icon_theme,
-                                     "gtk3-demo",
+                                     "face-cool",
                                      NULL,
                                      32, 1,
                                      gtk_widget_get_direction (widget),
                                      0);
-  texture = gtk_icon_paintable_download_texture (icon);
-  g_object_unref (icon);
-  g_assert (texture);
+  nuclear = gtk_nuclear_animation_new ();
 
   /* get start of buffer; each insertion will revalidate the
    * iterator to point to just after the inserted text.
@@ -239,9 +238,11 @@ insert_text (GtkTextView *view)
                                             "heading", NULL);
 
   gtk_text_buffer_insert (buffer, &iter, "The buffer can have images in it: ", -1);
-  gtk_text_buffer_insert_texture (buffer, &iter, texture);
-  gtk_text_buffer_insert_texture (buffer, &iter, texture);
-  gtk_text_buffer_insert_texture (buffer, &iter, texture);
+  gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (icon));
+  gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (icon));
+
+  gtk_text_buffer_insert_paintable (buffer, &iter, nuclear);
+
   gtk_text_buffer_insert (buffer, &iter, " for example.\n\n", -1);
 
   gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Spacing. ", -1,
@@ -386,7 +387,8 @@ insert_text (GtkTextView *view)
 
   gtk_text_buffer_end_irreversible_action (buffer);
 
-  g_object_unref (texture);
+  g_object_unref (icon);
+  g_object_unref (nuclear);
 }
 
 static gboolean
index db7d3485e328df840428de2794b8e19d435ad660..4a0de2a1411e9907258ddc35934e939c9136848d 100644 (file)
@@ -1259,9 +1259,8 @@ _gtk_text_btree_insert (GtkTextIter *iter,
 }
 
 static void
-insert_texture_or_widget_segment (GtkTextIter        *iter,
-                                  GtkTextLineSegment *seg)
-
+insert_paintable_or_widget_segment (GtkTextIter        *iter,
+                                    GtkTextLineSegment *seg)
 {
   GtkTextIter start;
   GtkTextLineSegment *prevPtr;
@@ -1297,19 +1296,21 @@ insert_texture_or_widget_segment (GtkTextIter        *iter,
   *iter = start;
   gtk_text_iter_forward_char (iter); /* skip forward past the segment */
 
-  DV (g_print ("invalidating due to inserting texture/widget (%s)\n", G_STRLOC));
+  DV (g_print ("invalidating due to inserting paintable/widget (%s)\n", G_STRLOC));
   _gtk_text_btree_invalidate_region (tree, &start, iter, FALSE);
 }
      
 void
-_gtk_text_btree_insert_texture (GtkTextIter *iter,
-                                GdkTexture  *texture)
+_gtk_text_btree_insert_paintable (GtkTextIter  *iter,
+                                  GdkPaintable *paintable)
 {
   GtkTextLineSegment *seg;
   
-  seg = _gtk_texture_segment_new (texture);
+  seg = _gtk_paintable_segment_new (paintable);
+  seg->body.paintable.tree = _gtk_text_iter_get_btree (iter);
+  seg->body.paintable.line = _gtk_text_iter_get_text_line (iter);
 
-  insert_texture_or_widget_segment (iter, seg);
+  insert_paintable_or_widget_segment (iter, seg);
 }
 
 void
@@ -1330,7 +1331,7 @@ _gtk_text_btree_insert_child_anchor (GtkTextIter        *iter,
   tree = seg->body.child.tree = _gtk_text_iter_get_btree (iter);
   seg->body.child.line = _gtk_text_iter_get_text_line (iter);
   
-  insert_texture_or_widget_segment (iter, seg);
+  insert_paintable_or_widget_segment (iter, seg);
 
   if (tree->child_anchor_table == NULL)
     tree->child_anchor_table = g_hash_table_new (NULL, NULL);
@@ -2380,7 +2381,7 @@ copy_segment (GString *string,
 
       /* printf ("  :%s\n", string->str); */
     }
-  else if (seg->type == &gtk_text_texture_type ||
+  else if (seg->type == &gtk_text_paintable_type ||
            seg->type == &gtk_text_child_type)
     {
       gboolean copy = TRUE;
index 5b5e331bddeae3ab5783fa9e6970b98849aa0f77..d333216b69b1c6c31f59302a2cb8fadb4c9a30e0 100644 (file)
@@ -63,13 +63,13 @@ gboolean _gtk_text_btree_is_end (GtkTextBTree       *tree,
 
 /* Indexable segment mutation */
 
-void _gtk_text_btree_delete        (GtkTextIter *start,
-                                    GtkTextIter *end);
-void _gtk_text_btree_insert        (GtkTextIter *iter,
-                                    const gchar *text,
-                                    gint         len);
-void _gtk_text_btree_insert_texture (GtkTextIter *iter,
-                                     GdkTexture  *texture);
+void _gtk_text_btree_delete           (GtkTextIter  *start,
+                                       GtkTextIter  *end);
+void _gtk_text_btree_insert           (GtkTextIter  *iter,
+                                       const gchar  *text,
+                                       gint          len);
+void _gtk_text_btree_insert_paintable (GtkTextIter  *iter,
+                                       GdkPaintable *texture);
 
 void _gtk_text_btree_insert_child_anchor (GtkTextIter        *iter,
                                           GtkTextChildAnchor *anchor);
@@ -161,6 +161,9 @@ gboolean _gtk_text_btree_get_iter_at_mark_name    (GtkTextBTree       *tree,
 void     _gtk_text_btree_get_iter_at_mark         (GtkTextBTree       *tree,
                                                    GtkTextIter        *iter,
                                                    GtkTextMark        *mark);
+void     _gtk_text_btree_get_iter_at_paintable    (GtkTextBTree       *tree,
+                                                   GtkTextIter        *iter,
+                                                   GtkTextLineSegment *seg);
 void     _gtk_text_btree_get_end_iter             (GtkTextBTree       *tree,
                                                    GtkTextIter        *iter);
 void     _gtk_text_btree_get_iter_at_line         (GtkTextBTree       *tree,
index 8bf2d50356874b0aeb9e008587055e243f0db351..abf6b6174d6b10f5893a2056513a51c742d326d8 100644 (file)
@@ -87,7 +87,7 @@ struct _ClipboardRequest
 
 enum {
   INSERT_TEXT,
-  INSERT_TEXTURE,
+  INSERT_PAINTABLE,
   INSERT_CHILD_ANCHOR,
   DELETE_RANGE,
   CHANGED,
@@ -128,9 +128,9 @@ static void gtk_text_buffer_real_insert_text           (GtkTextBuffer     *buffe
                                                         GtkTextIter       *iter,
                                                         const gchar       *text,
                                                         gint               len);
-static void gtk_text_buffer_real_insert_texture        (GtkTextBuffer     *buffer,
+static void gtk_text_buffer_real_insert_paintable      (GtkTextBuffer     *buffer,
                                                         GtkTextIter       *iter,
-                                                        GdkTexture        *texture);
+                                                        GdkPaintable      *paintable);
 static void gtk_text_buffer_real_insert_anchor         (GtkTextBuffer     *buffer,
                                                         GtkTextIter       *iter,
                                                         GtkTextChildAnchor *anchor);
@@ -434,7 +434,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
   object_class->get_property = gtk_text_buffer_get_property;
  
   klass->insert_text = gtk_text_buffer_real_insert_text;
-  klass->insert_texture = gtk_text_buffer_real_insert_texture;
+  klass->insert_paintable = gtk_text_buffer_real_insert_paintable;
   klass->insert_child_anchor = gtk_text_buffer_real_insert_anchor;
   klass->delete_range = gtk_text_buffer_real_delete_range;
   klass->apply_tag = gtk_text_buffer_real_apply_tag;
@@ -596,33 +596,33 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                               _gtk_marshal_VOID__BOXED_STRING_INTv);
 
   /**
-   * GtkTextBuffer::insert-texture:
+   * GtkTextBuffer::insert-paintable:
    * @textbuffer: the object which received the signal
-   * @location: position to insert @texture in @textbuffer
-   * @texture: the #GdkTexture to be inserted
+   * @location: position to insert @paintable in @textbuffer
+   * @paintable: the #GdkPaintable to be inserted
    *
-   * The ::insert-texture signal is emitted to insert a #GdkTexture
+   * The ::insert-paintable signal is emitted to insert a #GdkPaintable
    * in a #GtkTextBuffer. Insertion actually occurs in the default handler.
    *
    * Note that if your handler runs before the default handler it must not
    * invalidate the @location iter (or has to revalidate it).
    * The default signal handler revalidates it to be placed after the
-   * inserted @texture.
+   * inserted @paintable.
    *
-   * See also: gtk_text_buffer_insert_texture().
+   * See also: gtk_text_buffer_insert_paintable().
    */
-  signals[INSERT_TEXTURE] =
-    g_signal_new (I_("insert-texture"),
+  signals[INSERT_PAINTABLE] =
+    g_signal_new (I_("insert-paintable"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,
-                  G_STRUCT_OFFSET (GtkTextBufferClass, insert_texture),
+                  G_STRUCT_OFFSET (GtkTextBufferClass, insert_paintable),
                   NULL, NULL,
                   _gtk_marshal_VOID__BOXED_OBJECT,
                   G_TYPE_NONE,
                   2,
                   GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE,
-                  GDK_TYPE_TEXTURE);
-  g_signal_set_va_marshaller (signals[INSERT_TEXTURE],
+                  GDK_TYPE_PAINTABLE);
+  g_signal_set_va_marshaller (signals[INSERT_PAINTABLE],
                               G_TYPE_FROM_CLASS (klass),
                               _gtk_marshal_VOID__BOXED_OBJECTv);
 
@@ -1519,19 +1519,19 @@ insert_range_untagged (GtkTextBuffer     *buffer,
             }
           else if (gtk_text_iter_get_char (&range_end) == GTK_TEXT_UNKNOWN_CHAR)
             {
-              GdkTexture *texture;
+              GdkPaintable *paintable;
               GtkTextChildAnchor *anchor;
 
-              texture = gtk_text_iter_get_texture (&range_end);
+              paintable = gtk_text_iter_get_paintable (&range_end);
               anchor = gtk_text_iter_get_child_anchor (&range_end);
 
-              if (texture)
+              if (paintable)
                 {
                   r = save_range (&range_start,
                                   &range_end,
                                   &end);
 
-                  gtk_text_buffer_insert_texture (buffer, iter, texture);
+                  gtk_text_buffer_insert_paintable (buffer, iter, paintable);
 
                   restore_range (r);
                   r = NULL;
@@ -1733,7 +1733,7 @@ gtk_text_buffer_real_insert_range (GtkTextBuffer     *buffer,
  * @start: a position in a #GtkTextBuffer
  * @end: another position in the same buffer as @start
  *
- * Copies text, tags, and texture between @start and @end (the order
+ * Copies text, tags, and paintables between @start and @end (the order
  * of @start and @end doesn’t matter) and inserts the copy at @iter.
  * Used instead of simply getting/inserting text because it preserves
  * images and tags. If @start and @end are in a different buffer from
@@ -2215,7 +2215,7 @@ gtk_text_buffer_get_text (GtkTextBuffer     *buffer,
  * the returned string do correspond to byte
  * and character indexes into the buffer. Contrast with
  * gtk_text_buffer_get_text(). Note that 0xFFFC can occur in normal
- * text as well, so it is not a reliable indicator that a texture or
+ * text as well, so it is not a reliable indicator that a paintable or
  * widget is in the buffer.
  *
  * Returns: (transfer full): an allocated UTF-8 string
@@ -2243,41 +2243,41 @@ gtk_text_buffer_get_slice (GtkTextBuffer     *buffer,
  */
 
 static void
-gtk_text_buffer_real_insert_texture (GtkTextBuffer *buffer,
-                                     GtkTextIter   *iter,
-                                     GdkTexture    *texture)
+gtk_text_buffer_real_insert_paintable (GtkTextBuffer *buffer,
+                                       GtkTextIter   *iter,
+                                       GdkPaintable  *paintable)
 { 
-  _gtk_text_btree_insert_texture (iter, texture);
+  _gtk_text_btree_insert_paintable (iter, paintable);
 
   g_signal_emit (buffer, signals[CHANGED], 0);
 }
 
 /**
- * gtk_text_buffer_insert_texture:
+ * gtk_text_buffer_insert_paintable:
  * @buffer: a #GtkTextBuffer
- * @iter: location to insert the texture
- * @texture: a #GdkTexture
+ * @iter: location to insert the paintable
+ * @paintable: a #GdkPaintable
  *
  * Inserts an image into the text buffer at @iter. The image will be
  * counted as one character in character counts, and when obtaining
  * the buffer contents as a string, will be represented by the Unicode
  * “object replacement character” 0xFFFC. Note that the “slice”
  * variants for obtaining portions of the buffer as a string include
- * this character for texture, but the “text” variants do
+ * this character for paintable, but the “text” variants do
  * not. e.g. see gtk_text_buffer_get_slice() and
  * gtk_text_buffer_get_text().
  **/
 void
-gtk_text_buffer_insert_texture (GtkTextBuffer *buffer,
-                                GtkTextIter   *iter,
-                                GdkTexture    *texture)
+gtk_text_buffer_insert_paintable (GtkTextBuffer *buffer,
+                                  GtkTextIter   *iter,
+                                  GdkPaintable    *paintable)
 {
   g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
   g_return_if_fail (iter != NULL);
-  g_return_if_fail (GDK_IS_TEXTURE (texture));
+  g_return_if_fail (GDK_IS_PAINTABLE (paintable));
   g_return_if_fail (gtk_text_iter_get_buffer (iter) == buffer);
 
-  g_signal_emit (buffer, signals[INSERT_TEXTURE], 0, iter, texture);
+  g_signal_emit (buffer, signals[INSERT_PAINTABLE], 0, iter, paintable);
 }
 
 /*
index 969db7f3d8b2cb4feaeadbf98c7dc303e6b46575..a844d94f5b0bd75ddd7be1270ab3231be73f9def 100644 (file)
@@ -85,7 +85,7 @@ struct _GtkTextBuffer
  * GtkTextBufferClass:
  * @parent_class: The object class structure needs to be the first.
  * @insert_text: The class handler for the #GtkTextBuffer::insert-text signal.
- * @insert_texture: The class handler for the #GtkTextBuffer::insert-texture signal.
+ * @insert_paintable: The class handler for the #GtkTextBuffer::insert-paintable signal.
  * @insert_child_anchor: The class handler for the #GtkTextBuffer::insert-child-anchor signal.
  * @delete_range: The class handler for the #GtkTextBuffer::delete-range signal.
  * @changed: The class handler for the #GtkTextBuffer::changed signal.
@@ -107,9 +107,9 @@ struct _GtkTextBufferClass
                                    const gchar        *new_text,
                                    gint                new_text_length);
 
-  void (* insert_texture)         (GtkTextBuffer      *buffer,
+  void (* insert_paintable)       (GtkTextBuffer      *buffer,
                                    GtkTextIter        *iter,
-                                   GdkTexture         *texture);
+                                   GdkPaintable       *paintable);
 
   void (* insert_child_anchor)    (GtkTextBuffer      *buffer,
                                    GtkTextIter        *iter,
@@ -267,11 +267,11 @@ gchar          *gtk_text_buffer_get_slice           (GtkTextBuffer     *buffer,
                                                      const GtkTextIter *end,
                                                      gboolean           include_hidden_chars);
 
-/* Insert a texture */
+/* Insert a paintable */
 GDK_AVAILABLE_IN_ALL
-void gtk_text_buffer_insert_texture        (GtkTextBuffer *buffer,
+void gtk_text_buffer_insert_paintable      (GtkTextBuffer *buffer,
                                             GtkTextIter   *iter,
-                                            GdkTexture    *texture);
+                                            GdkPaintable  *texture);
 
 /* Insert a child anchor */
 GDK_AVAILABLE_IN_ALL
index 2ce394c94e58e117bd1b2fd544a7322e693a8b1f..0a2e6163dd238f01ffe799eb69d6e7124e363c78 100644 (file)
       }                                                                 \
   } G_STMT_END
 
-#define TEXTURE_SEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \
-        + sizeof (GtkTextTexture)))
+#define PAINTABLE_SEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \
+        + sizeof (GtkTextPaintable)))
 
 #define WIDGET_SEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \
         + sizeof (GtkTextChildBody)))
 
+
+static void
+paintable_invalidate_size (GdkPaintable       *paintable,
+                           GtkTextLineSegment *seg)
+{
+  if (seg->body.paintable.tree)
+    {
+      GtkTextIter start, end;
+
+      _gtk_text_btree_get_iter_at_paintable (seg->body.paintable.tree, &start, seg);
+      end = start;
+      gtk_text_iter_forward_char (&end);
+
+      _gtk_text_btree_invalidate_region (seg->body.paintable.tree, &start, &end, FALSE);
+    }
+}
+
+static void
+paintable_invalidate_contents (GdkPaintable       *paintable,
+                               GtkTextLineSegment *seg)
+{
+  /* These do the same anyway */
+  paintable_invalidate_size (paintable, seg);
+}
+
 static GtkTextLineSegment *
-texture_segment_cleanup_func (GtkTextLineSegment *seg,
-                              GtkTextLine        *line)
+paintable_segment_cleanup_func (GtkTextLineSegment *seg,
+                                GtkTextLine        *line)
 {
-  /* nothing */
+  seg->body.paintable.line = line;
+
   return seg;
 }
 
 static int
-texture_segment_delete_func (GtkTextLineSegment *seg,
-                             GtkTextLine        *line,
-                             gboolean            tree_gone)
+paintable_segment_delete_func (GtkTextLineSegment *seg,
+                               GtkTextLine        *line,
+                               gboolean            tree_gone)
 {
-  if (seg->body.texture.texture)
-    g_object_unref (seg->body.texture.texture);
+  GdkPaintable *paintable;
+  guint flags;
 
-  g_slice_free1 (TEXTURE_SEG_SIZE, seg);
+  seg->body.paintable.tree = NULL;
+  seg->body.paintable.line = NULL;
+
+  paintable = seg->body.paintable.paintable;
+  if (paintable)
+    {
+      flags = gdk_paintable_get_flags (paintable);
+      if ((flags & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
+        g_signal_handlers_disconnect_by_func (paintable, G_CALLBACK (paintable_invalidate_contents), seg);
+
+      if ((flags & GDK_PAINTABLE_STATIC_SIZE) == 0)
+        g_signal_handlers_disconnect_by_func (paintable, G_CALLBACK (paintable_invalidate_size), seg);
+
+      g_object_unref (paintable);
+    }
+
+  g_slice_free1 (PAINTABLE_SEG_SIZE, seg);
 
   return 0;
 }
 
 static void
-texture_segment_check_func (GtkTextLineSegment *seg,
-                            GtkTextLine        *line)
+paintable_segment_check_func (GtkTextLineSegment *seg,
+                              GtkTextLine        *line)
 {
   if (seg->next == NULL)
-    g_error ("texture segment is the last segment in a line");
+    g_error ("paintable segment is the last segment in a line");
 
   if (seg->byte_count != GTK_TEXT_UNKNOWN_CHAR_UTF8_LEN)
-    g_error ("texture segment has byte count of %d", seg->byte_count);
+    g_error ("paintable segment has byte count of %d", seg->byte_count);
 
   if (seg->char_count != 1)
-    g_error ("texture segment has char count of %d", seg->char_count);
+    g_error ("paintable segment has char count of %d", seg->char_count);
 }
 
-
-const GtkTextLineSegmentClass gtk_text_texture_type = {
-  "texture",                          /* name */
-  FALSE,                                            /* leftGravity */
-  NULL,                                          /* splitFunc */
-  texture_segment_delete_func,                             /* deleteFunc */
-  texture_segment_cleanup_func,                            /* cleanupFunc */
-  NULL,                                                    /* lineChangeFunc */
-  texture_segment_check_func                               /* checkFunc */
+const GtkTextLineSegmentClass gtk_text_paintable_type = {
+  "paintable",                          /* name */
+  FALSE,                                /* leftGravity */
+  NULL,                                 /* splitFunc */
+  paintable_segment_delete_func,        /* deleteFunc */
+  paintable_segment_cleanup_func,       /* cleanupFunc */
+  NULL,                                 /* lineChangeFunc */
+  paintable_segment_check_func          /* checkFunc */
 
 };
 
 GtkTextLineSegment *
-_gtk_texture_segment_new (GdkTexture *texture)
+_gtk_paintable_segment_new (GdkPaintable *paintable)
 {
   GtkTextLineSegment *seg;
+  guint flags;
 
-  seg = g_slice_alloc (TEXTURE_SEG_SIZE);
+  seg = g_slice_alloc (PAINTABLE_SEG_SIZE);
 
-  seg->type = &gtk_text_texture_type;
+  seg->type = &gtk_text_paintable_type;
 
   seg->next = NULL;
 
@@ -142,9 +184,24 @@ _gtk_texture_segment_new (GdkTexture *texture)
   seg->byte_count = GTK_TEXT_UNKNOWN_CHAR_UTF8_LEN;
   seg->char_count = 1;
 
-  seg->body.texture.texture = texture;
+  seg->body.paintable.paintable = paintable;
+  seg->body.paintable.tree = NULL;
+  seg->body.paintable.line = NULL;
+
+  flags = gdk_paintable_get_flags (paintable);
+  if ((flags & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
+    g_signal_connect (paintable,
+                      "invalidate-contents",
+                      G_CALLBACK (paintable_invalidate_contents),
+                      seg);
+
+  if ((flags & GDK_PAINTABLE_STATIC_SIZE) == 0)
+    g_signal_connect (paintable,
+                      "invalidate-size",
+                      G_CALLBACK (paintable_invalidate_size),
+                      seg);
 
-  g_object_ref (texture);
+  g_object_ref (paintable);
 
   return seg;
 }
index 6473d455af343d64ed796933cc18904be9d474fb..33a395efc420d6a2b298af4ec21b9955a2b303ae 100644 (file)
 
 G_BEGIN_DECLS
 
-typedef struct _GtkTextTexture GtkTextTexture;
+typedef struct _GtkTextPaintable GtkTextPaintable;
 
-struct _GtkTextTexture
+struct _GtkTextPaintable
 {
-  GdkTexture *texture;
+  GdkPaintable *paintable;
+  GtkTextBTree *tree;
+  GtkTextLine *line;
 };
 
-GtkTextLineSegment *_gtk_texture_segment_new (GdkTexture *texture);
+GtkTextLineSegment *_gtk_paintable_segment_new (GdkPaintable *paintable);
 
 typedef struct _GtkTextChildBody GtkTextChildBody;
 
index c031c98fa182a8262f31240533264f45d7738d16..c4c1bfc0246d03619a8200b57990f2f4582a2400 100644 (file)
@@ -173,7 +173,7 @@ gtk_text_iter_make_surreal (const GtkTextIter *_iter)
       _gtk_text_btree_get_chars_changed_stamp (iter->tree))
     {
       g_warning ("Invalid text buffer iterator: either the iterator "
-                 "is uninitialized, or the characters/textures/widgets "
+                 "is uninitialized, or the characters/paintables/widgets "
                  "in the buffer have been modified since the iterator "
                  "was created.\nYou must use marks, character numbers, "
                  "or line numbers to preserve a position across buffer "
@@ -896,7 +896,7 @@ gtk_text_iter_get_char (const GtkTextIter *iter)
  * such as images.  Because images are encoded in the slice, byte and
  * character offsets in the returned array will correspond to byte
  * offsets in the text buffer. Note that 0xFFFC can occur in normal
- * text as well, so it is not a reliable indicator that a texture or
+ * text as well, so it is not a reliable indicator that a paintable or
  * widget is in the buffer.
  *
  * Returns: (transfer full): slice of text from the buffer
@@ -990,16 +990,16 @@ gtk_text_iter_get_visible_text (const GtkTextIter  *start,
 }
 
 /**
- * gtk_text_iter_get_texture:
+ * gtk_text_iter_get_paintable:
  * @iter: an iterator
  *
- * If the element at @iter is a texture, the texture is returned
+ * If the element at @iter is a paintable, the paintable is returned
  * (with no new reference count added). Otherwise, %NULL is returned.
  *
- * Returns: (transfer none): the texture at @iter
+ * Returns: (transfer none): the paintable at @iter
  **/
-GdkTexture *
-gtk_text_iter_get_texture (const GtkTextIter *iter)
+GdkPaintable *
+gtk_text_iter_get_paintable (const GtkTextIter *iter)
 {
   GtkTextRealIter *real;
 
@@ -1012,10 +1012,10 @@ gtk_text_iter_get_texture (const GtkTextIter *iter)
 
   check_invariants (iter);
 
-  if (real->segment->type != &gtk_text_texture_type)
+  if (real->segment->type != &gtk_text_paintable_type)
     return NULL;
   else
-    return real->segment->body.texture.texture;
+    return real->segment->body.paintable.paintable;
 }
 
 /**
@@ -2444,7 +2444,7 @@ gtk_text_iter_backward_chars (GtkTextIter *iter, gint count)
  * @iter: a #GtkTextIter
  * @count: number of chars to move
  *
- * Moves forward by @count text characters (textures, widgets,
+ * Moves forward by @count text characters (paintables, widgets,
  * etc. do not count as characters for this). Equivalent to moving
  * through the results of gtk_text_iter_get_text(), rather than
  * gtk_text_iter_get_slice().
@@ -2465,7 +2465,7 @@ gtk_text_iter_forward_text_chars  (GtkTextIter *iter,
  * @iter: a #GtkTextIter
  * @count: number of chars to move
  *
- * Moves backward by @count text characters (textures, widgets,
+ * Moves backward by @count text characters (paintables, widgets,
  * etc. do not count as characters for this). Equivalent to moving
  * through the results of gtk_text_iter_get_text(), rather than
  * gtk_text_iter_get_slice().
@@ -5666,6 +5666,20 @@ _gtk_text_btree_get_iter_at_mark_name (GtkTextBTree *tree,
     }
 }
 
+void
+_gtk_text_btree_get_iter_at_paintable (GtkTextBTree *tree,
+                                       GtkTextIter *iter,
+                                       GtkTextLineSegment *seg)
+{
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (tree != NULL);
+
+  iter_init_from_segment (iter, tree,
+                          seg->body.paintable.line, seg);
+  g_assert (seg->body.paintable.line == _gtk_text_iter_get_text_line (iter));
+  check_invariants (iter);
+}
+
 void
 _gtk_text_btree_get_iter_at_mark (GtkTextBTree *tree,
                                   GtkTextIter *iter,
index 890244e459c785e05a09385217532a3ec70f4464..9655bcfe66e3f6e5ec52a6171ba8e38ffe4e2ede 100644 (file)
@@ -38,7 +38,7 @@ G_BEGIN_DECLS
  * GtkTextSearchFlags:
  * @GTK_TEXT_SEARCH_VISIBLE_ONLY: Search only visible data. A search match may
  * have invisible text interspersed.
- * @GTK_TEXT_SEARCH_TEXT_ONLY: Search only text. A match may have textures or
+ * @GTK_TEXT_SEARCH_TEXT_ONLY: Search only text. A match may have paintables or
  * child widgets mixed inside the matched range.
  * @GTK_TEXT_SEARCH_CASE_INSENSITIVE: The text will be matched regardless of
  * what case it is in.
@@ -47,7 +47,7 @@ G_BEGIN_DECLS
  *
  * If neither #GTK_TEXT_SEARCH_VISIBLE_ONLY nor #GTK_TEXT_SEARCH_TEXT_ONLY are
  * enabled, the match must be exact; the special 0xFFFC character will match
- * embedded textures or child widgets.
+ * embedded paintables or child widgets.
  */
 typedef enum {
   GTK_TEXT_SEARCH_VISIBLE_ONLY     = 1 << 0,
@@ -155,9 +155,9 @@ gchar   *gtk_text_iter_get_visible_text  (const GtkTextIter  *start,
                                           const GtkTextIter  *end);
 
 GDK_AVAILABLE_IN_ALL
-GdkTexture * gtk_text_iter_get_texture (const GtkTextIter *iter);
+GdkPaintable *gtk_text_iter_get_paintable (const GtkTextIter *iter);
 GDK_AVAILABLE_IN_ALL
-GSList  *  gtk_text_iter_get_marks  (const GtkTextIter *iter);
+GSList      *gtk_text_iter_get_marks      (const GtkTextIter *iter);
 
 GDK_AVAILABLE_IN_ALL
 GtkTextChildAnchor* gtk_text_iter_get_child_anchor (const GtkTextIter *iter);
index 5a2b4197306b29e35cd62cd3e7eaf0dcd653ea0c..406437c5fdd48292e07c1664fecf087c38e0cac7 100644 (file)
@@ -1710,20 +1710,31 @@ add_text_attrs (GtkTextLayout      *layout,
 }
 
 static void
-add_texture_attrs (GtkTextLayout      *layout,
-                   GtkTextLineDisplay *display,
-                   GtkTextAttributes  *style,
-                   GtkTextLineSegment *seg,
-                   PangoAttrList      *attrs,
-                   gint                start)
+add_paintable_attrs (GtkTextLayout      *layout,
+                     GtkTextLineDisplay *display,
+                     GtkTextAttributes  *style,
+                     GtkTextLineSegment *seg,
+                     PangoAttrList      *attrs,
+                     gint                start)
 {
   PangoAttribute *attr;
   PangoRectangle logical_rect;
-  GtkTextTexture *texture = &seg->body.texture;
+  GtkTextPaintable *paintable = &seg->body.paintable;
   gint width, height;
 
-  width = gdk_texture_get_width (texture->texture);
-  height = gdk_texture_get_height (texture->texture);
+  width = gdk_paintable_get_intrinsic_width (paintable->paintable);
+  height = gdk_paintable_get_intrinsic_height (paintable->paintable);
+
+  /* Pick *some* default size */
+  if (width == 0)
+    width = 32;
+  if (height == 0)
+    {
+      double aspect = gdk_paintable_get_intrinsic_aspect_ratio (paintable->paintable);
+      if (aspect == 0)
+        aspect = 1.0;
+      height = width / aspect;
+    }
 
   logical_rect.x = 0;
   logical_rect.y = -height * PANGO_SCALE;
@@ -1731,7 +1742,7 @@ add_texture_attrs (GtkTextLayout      *layout,
   logical_rect.height = height * PANGO_SCALE;
 
   attr = pango_attr_shape_new_with_data (&logical_rect, &logical_rect,
-                                        texture->texture, NULL, NULL);
+                                        paintable->paintable, NULL, NULL);
   attr->start_index = start;
   attr->end_index = start + seg->byte_count;
   pango_attr_list_insert (attrs, attr);
@@ -2149,7 +2160,7 @@ gtk_text_layout_update_display_cursors (GtkTextLayout      *layout,
     {
       /* Displayable segments */
       if (seg->type == &gtk_text_char_type ||
-          seg->type == &gtk_text_texture_type ||
+          seg->type == &gtk_text_paintable_type ||
           seg->type == &gtk_text_child_type)
         {
           gtk_text_layout_get_iter_at_line (layout, &iter, line,
@@ -2346,14 +2357,14 @@ gtk_text_layout_create_display (GtkTextLayout *layout,
     {
       /* Displayable segments */
       if (seg->type == &gtk_text_char_type ||
-          seg->type == &gtk_text_texture_type ||
+          seg->type == &gtk_text_paintable_type ||
           seg->type == &gtk_text_child_type)
         {
           style = get_style (layout, tags);
           initial_toggle_segments = FALSE;
 
           /* We have to delay setting the paragraph values until we
-           * hit the first texture or text segment because toggles at
+           * hit the first paintable or text segment because toggles at
            * the beginning of the paragraph should affect the
            * paragraph-global values
            */
@@ -2430,15 +2441,15 @@ gtk_text_layout_create_display (GtkTextLayout *layout,
                                   &last_scale_attr,
                                   &last_fallback_attr);
                 }
-              else if (seg->type == &gtk_text_texture_type)
+              else if (seg->type == &gtk_text_paintable_type)
                 {
                   add_generic_attrs (layout,
                                      &style->appearance,
                                      seg->byte_count,
                                      attrs, layout_byte_offset,
                                      size_only, FALSE);
-                  add_texture_attrs (layout, display, style,
-                                     seg, attrs, layout_byte_offset);
+                  add_paintable_attrs (layout, display, style,
+                                       seg, attrs, layout_byte_offset);
                   memcpy (text + layout_byte_offset, _gtk_text_unknown_char_utf8,
                           seg->byte_count);
                   layout_byte_offset += seg->byte_count;
@@ -4072,6 +4083,21 @@ render_para (GskPangoRenderer   *crenderer,
   pango_layout_iter_free (iter);
 }
 
+static gboolean
+snapshot_shape (PangoAttrShape         *attr,
+                GdkSnapshot            *snapshot,
+                double                  width,
+                double                  height)
+{
+  if (GDK_IS_PAINTABLE (attr->data))
+    {
+      gdk_paintable_snapshot (GDK_PAINTABLE (attr->data), snapshot, width, height);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
 void
 gtk_text_layout_snapshot (GtkTextLayout      *layout,
                           GtkWidget          *widget,
@@ -4106,6 +4132,8 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
 
   crenderer = gsk_pango_renderer_acquire ();
 
+  gsk_pango_renderer_set_shape_handler (crenderer, snapshot_shape);
+
   crenderer->widget = widget;
   crenderer->snapshot = snapshot;
   crenderer->fg_color = color;
index 690edba4fec80a769995a1973c58f35818a9b966..ed987742ff83ea160f0f2b289a9181d65be5c696 100644 (file)
@@ -142,10 +142,10 @@ struct _GtkTextLineSegment {
     char chars[4];                      /* Characters that make up character
                                          * info.  Actual length varies to
                                          * hold as many characters as needed.*/
-    GtkTextToggleBody toggle;              /* Information about tag toggle. */
-    GtkTextMarkBody mark;              /* Information about mark. */
-    GtkTextTexture texture;            /* Child texture */
-    GtkTextChildBody child;            /* Child widget */
+    GtkTextToggleBody toggle;           /* Information about tag toggle. */
+    GtkTextMarkBody mark;               /* Information about mark. */
+    GtkTextPaintable paintable;         /* Child texture */
+    GtkTextChildBody child;             /* Child widget */
   } body;
 };
 
index a66114778bf1bf59c3f629cd1324efb6d35c734b..02520eab3abcf040b3e398dd05e890c7e31122bb 100644 (file)
@@ -50,7 +50,7 @@ extern G_GNUC_INTERNAL const GtkTextLineSegmentClass gtk_text_left_mark_type;
 extern G_GNUC_INTERNAL const GtkTextLineSegmentClass gtk_text_right_mark_type;
 
 /* In gtktextchild.c */
-extern G_GNUC_INTERNAL const GtkTextLineSegmentClass gtk_text_texture_type;
+extern G_GNUC_INTERNAL const GtkTextLineSegmentClass gtk_text_paintable_type;
 extern G_GNUC_INTERNAL const GtkTextLineSegmentClass gtk_text_child_type;
 
 /*
index d4bb416a2b7d94c43ac45a88957aed749c6197b8..33b3048d3d382e939e3206f64af7af9d61a3b3de 100644 (file)
@@ -686,11 +686,11 @@ fill_buffer (GtkTextBuffer *buffer)
 
       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
 
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (texture));
 
       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 1);
 
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (texture));
 
       str = g_strdup_printf ("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
                             i);
@@ -706,20 +706,20 @@ fill_buffer (GtkTextBuffer *buffer)
                               "Spanish (Espa\303\261ol) \302\241Hola! / French (Fran\303\247ais) Bonjour, Salut / German (Deutsch S\303\274d) Gr\303\274\303\237 Gott (testing Latin-1 chars encoded in UTF8)\nThai (we can't display this, just making sure we don't crash)  (\340\270\240\340\270\262\340\270\251\340\270\262\340\271\204\340\270\227\340\270\242)  \340\270\252\340\270\247\340\270\261\340\270\252\340\270\224\340\270\265\340\270\204\340\270\243\340\270\261\340\270\232, \340\270\252\340\270\247\340\270\261\340\270\252\340\270\224\340\270\265\340\270\204\340\271\210\340\270\260\n",
                               -1);
 
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE(texture));
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE(texture));
 
       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 4);
 
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE(texture));
 
       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 7);
 
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE(texture));
 
       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 8);
 
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE(texture));
 
       gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 8);
       iter2 = iter;